define(function() {
	var events = function(name) {
		this.name = name || '未知';
		this.id = Guid.raw();
		this.evtMap = {};

		return this;
	};

	events.prototype = {
		/**
		 * 注册一个消息事件
		 * @param e {string} 消息
		 * @param listenerId {string} 监听者ID
		 * @param callback {callback} 回调方法
		 * @param ev {any} 环境参数
		 * @return {event} 消息管理器对象
		 */
		register : function(e, listenerId, callback, ev) {
			if (!this.evtMap[e])
				this.evtMap[e] = {};

			if (!this.evtMap[e][listenerId])
				this.evtMap[e][listenerId] = []

			this.evtMap[e][listenerId].push({
				callback : callback,
				ev : ev
			});
			return this;
		},

		/**
		 * 一次性注册多种消息
		 * @param es {array} 消息数组
		 * @param listenerId
		 * @param callback
		 * @param ev
		 */
		registerAll : function(es, listenerId, callback, ev) {
			var a = this;
			$.each(es, function(i, v) {
				a.register(v, listenerId, callback, ev);
			})
			return a;
		},

		/**
		 * 移除一个已经注册的消息事件，当消息未指定时，移除该监听者的所有消息事件
		 * @param listenerId {string} 监听者ID
		 * @param [e] {string} 消息
		 * @return {event} 消息管理器对象
		 */
		remove : function(listenerId, e) {
			$F.log('Event', '移除事件监听者: ' + listenerId + (e === undefined ? '' : ', 在消息：' + e))
			if (e === undefined) {
				for (e in this.evtMap) {
					delete this.evtMap[e][listenerId];
				}
			} else {
				if(this.evtMap[e])
					delete this.evtMap[e][listenerId];
			}
			return this;
		},

		/**
		 * 广播一个消息
		 * @param e {string} 消息
		 * @param [value] {any} 消息的值
		 * @param [scope] {string} 消息针对的监听对象
		 */
		fire : function(e, value, scope) {
			console.log('Event fire: ' + e, value);
			return this.notify(e, value, scope);
		},
		notify : function(e, value, scope) {
			var a = this;
			if (a.evtMap[e]) {
				for (var id in a.evtMap[e]) {
					if (!scope || scope == id) {
						$F.logGroup('Event - ' + e, '触发监听器：' + id);
						$.each(a.evtMap[e][id], function(i, listener) {
							if ($.isFunction(listener.callback)) {
								try {
									listener.callback(value, listener.ev);
								} catch (e) {
									if (!(e instanceof StopException))
										$F.err('Event - notify', e)
								}
							}
						});
						$F.logGroupEnd();
					}
				}
			}
			return this;
		}
	};

	return {
		create : function(name) {
			return new events(name);
		}
	}
});